// Ofri Keidar 302933981 group 05

package controller;

import static org.junit.Assert.*;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import model.SystemDataManager;
import model.database.DBException;
import model.database.StoreDB;

import org.junit.After;
import org.junit.Test;

import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import controller.SystemController;

public class AdministratorControllerTester {
	
	/**
	 * Method that after each test.
	 * This method deletes from database test record that was
	 * added at both tests
	 */
	@After
	public void teardown() {
		
		// connection to database
		Connection connection = null;
		MysqlDataSource ds = new MysqlConnectionPoolDataSource();

		// set server and database
		ds.setServerName(TestCommons.SERVER_NAME);
		ds.setDatabaseName(TestCommons.DB_NAME);

		try {
			
			// connect to database
			connection = ds.getConnection(TestCommons.DB_USER, TestCommons.DB_PWD);
			Statement statement = connection.createStatement();

			// delete test user record
			String query = String.format("DELETE FROM %s WHERE %s = '%s'", 
					TestCommons.PASSWORDS_TABLE, TestCommons.USER_NAME, TestCommons.TEST_USER_NAME);
			
			// execute query
			if (statement.executeUpdate(query) == 0) {

				// could not delete user record
				fail();
			}
						
		} catch (SQLException e) {

			// check reason for error
			e.printStackTrace();
			
			// tests should fail in case of exception
			fail();
			
		} finally { // close connection
			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException e) {

					// check reason for error
					e.printStackTrace();
					
					// test should fail in case of exception
					fail();
				}
			}
		}
	}
	
	/**
	 * Adds a test user record and verifies that transaction's return value is success
	 */
	@Test
	public void addUser() {

		try {

			// create database
			StoreDB db = new StoreDB();
			
			// create model
			SystemDataManager dataManager = new SystemDataManager(db);
			
			// create controller
			SystemController controller = new SystemController(dataManager);

			// add user record
			boolean couldAdd = controller.addUserRecord(TestCommons.TEST_USER_NAME, CommonValues.permissions.EMPLOYEE);
			
			assertEquals(true, couldAdd);

			// add same user again
			couldAdd = controller.addUserRecord(TestCommons.TEST_USER_NAME, CommonValues.permissions.EMPLOYEE);
			
			// compare values
			assertEquals(false, couldAdd);

			
		} catch (DBException e) {

			// check reason for error
			e.printStackTrace();
			
			// test should fail in case of exception
			fail();
		}
	}

	/**
	 * Adds twice test user record, and verifies that on second time,
	 * transaction's return value if not success
	 */
	@Test
	public void addDuplicateUser() {

		try {

			// create database
			StoreDB db = new StoreDB();
			
			// create model
			SystemDataManager dataManager = new SystemDataManager(db);
			
			// create controller
			SystemController controller = new SystemController(dataManager);

			// add user record
			boolean couldAdd = controller.addUserRecord(TestCommons.TEST_USER_NAME, CommonValues.permissions.EMPLOYEE);

			// add same user again
			couldAdd = controller.addUserRecord(TestCommons.TEST_USER_NAME, CommonValues.permissions.EMPLOYEE);
			
			// compare values
			assertEquals(false, couldAdd);
			
		} catch (DBException e) {

			// check reason for error
			e.printStackTrace();
			
			// test should fail in case of exception
			fail();
		}
	}
}